package com.sunshine.lnuplus.utils;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class CryptoUtils {
    /*   算法/模式/填充 */
    private static final String CipherMode = "AES/ECB/PKCS5Padding";

    /*  创建密钥  */
    private static SecretKeySpec createKey(String password) {
        byte[] data = null;
        if (password == null) {
            password = "";
        }
        StringBuilder sb = new StringBuilder(32);
        sb.append(password);
        while (sb.length() < 32) {
            sb.append("0");
        }
        if (sb.length() > 32) {
            sb.setLength(32);
        }

        data = sb.toString().getBytes(StandardCharsets.UTF_8);
        return new SecretKeySpec(data, "AES");
    }

    /* 加密字节数据  */
    private static byte[] encrypt(byte[] content, String password) {
        try {
            SecretKeySpec key = createKey(password);
            Cipher cipher = Cipher.getInstance(CipherMode);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            return cipher.doFinal(content);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /*加密(结果为16进制字符串)  */
    public static String encrypt(String content, String password) {
        byte[] data = null;
        try {
            data = content.getBytes(StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
        data = encrypt(data, password);
        return byte2hex(data);
    }

    /*解密字节数组*/
    private static byte[] decrypt(byte[] content, String password) {
        try {
            SecretKeySpec key = createKey(password);
            Cipher cipher = Cipher.getInstance(CipherMode);
            cipher.init(Cipher.DECRYPT_MODE, key);
            return cipher.doFinal(content);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /*解密16进制的字符串为字符串  */
    public static String decrypt(String content, String password) {
        byte[] data = null;
        try {
            data = hex2byte(content);
        } catch (Exception e) {
            e.printStackTrace();
        }
        data = decrypt(data, password);
        if (data == null) return "";
        String result = null;
        result = new String(data, StandardCharsets.UTF_8);
        return result;
    }

    /*字节数组转成16进制字符串  */
    private static String byte2hex(byte[] b) { // 一个字节的数，
        StringBuilder sb = new StringBuilder(b.length * 2);
        String tmp = "";
        for (byte value : b) {
            // 整数转成十六进制表示
            tmp = (Integer.toHexString(value & 0XFF));
            if (tmp.length() == 1) {
                sb.append("0");
            }
            sb.append(tmp);
        }
        return sb.toString().toUpperCase(); // 转成大写
    }

    /*将hex字符串转换成字节数组 */
    private static byte[] hex2byte(String inputString) {
        if (inputString == null || inputString.length() < 2) {
            return new byte[0];
        }
        inputString = inputString.toLowerCase();
        int l = inputString.length() / 2;
        byte[] result = new byte[l];
        for (int i = 0; i < l; ++i) {
            String tmp = inputString.substring(2 * i, 2 * i + 2);
            try {
                result[i] = (byte) (Integer.parseInt(tmp, 16) & 0xFF);
            } catch (NumberFormatException e) {
                e.printStackTrace();
                result[i] = Byte.parseByte("");
            }

        }
        return result;
    }

    /**
     * 以下两个函数参考了壮飞的代码，但是不开源了我找不到出处了...
     * @param password
     * @return
     */
    public static String superEncrypt(String password) {
        try {
            SecretKeySpec secretKeySpec = new SecretKeySpec(MessageDigest.getInstance("MD5").digest(getSuperEncryptKey("friday_syllabus").getBytes(StandardCharsets.UTF_8)), "AES");
            Cipher localCipher = Cipher.getInstance("AES");
            localCipher.init(1, secretKeySpec);
            password = byte2hex(localCipher.doFinal(URLEncoder.encode(password, "utf-8").getBytes(StandardCharsets.UTF_8)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return password;
    }

    //获取加密Key
    public static String getSuperEncryptKey(String paramString) {
        int j = 0;
        String encrypt = "";
        char[] array1 = "0123456789abcdef".toCharArray();
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(paramString.getBytes());
            byte[] md5bytes = md.digest();//md5值
            char[] keychars = new char[32];
            for (int i = 0; i < 16; i++) {
                int k = md5bytes[i];
                int m = j + 1;
                keychars[j] = array1[(k >>> 4 & 0xF)];
                j = m + 1;
                keychars[m] = array1[(k & 0xF)];
            }
            encrypt = new String(keychars).toUpperCase();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return encrypt;
    }

    public static void handleSSLHandshake() {
        try {
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }

                @Override
                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                }
            }};

            SSLContext sc = SSLContext.getInstance("TLS");
            // trustAllCerts信任所有的证书
            sc.init(null, trustAllCerts, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
        } catch (Exception ignored) {
        }
    }


}